Tổng quan: Ở bài tập này, chúng ta sẽ thực hành lập trình một số hàm xử lí ảnh cơ bản
Yêu cầu thư viện: OpenCV 3.3, matplotlib
from IPython.display import Image
import matplotlib.pyplot as plt
import cv2
import numpy as np
Biểu đồ Histogram của ảnh là một dạng biểu đồ biểu diễn sự phân bố của số lượng điểm ảnh tương ứng với mức độ sáng tối của bức ảnh.
Để tính được Histogram của một ảnh, ta có thể dùng một trong các hàm sau:
img = cv2.imread('HoGuom.jpg', cv2.IMREAD_GRAYSCALE)
plt.imshow(img, cmap='gray')
plt.hist(img.ravel(),256,[0,256]); plt.show()
Dựa vào Histogram có thể biết được bức ảnh là tối (dark) hay sáng (bright).
img = cv2.imread('dark.jpg', cv2.IMREAD_GRAYSCALE)
plt.subplot(211)
plt.imshow(img, cmap='gray')
plt.subplot(212)
plt.hist(img.ravel(),256,[0,256])
plt.show()
img = cv2.imread('bright.jpg', cv2.IMREAD_GRAYSCALE)
plt.subplot(211)
plt.imshow(img, cmap='gray')
plt.subplot(212)
plt.hist(img.ravel(),256,[0,256])
plt.show()
Đối với ảnh màu, ta có thể xem Histogram của từng kênh màu
Image('HoGuom.jpg')
img = cv2.imread('HoGuom.jpg', cv2.IMREAD_COLOR)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img[:,:,[0,1]] = 0
plt.imshow(img)
img = cv2.imread('HoGuom.jpg', cv2.IMREAD_COLOR)
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv2.calcHist([img],[i],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.show()
Thư viện OpenCV cung cấp hàm để Equalize Histogram:
Image('unequalized.jpg')
img = cv2.imread('unequalized.jpg', cv2.IMREAD_GRAYSCALE)
equ = cv2.equalizeHist(img)
plt.imshow(equ, cmap='gray')
plt.subplot(211)
plt.hist(img.ravel(),256,[0,256])
plt.subplot(212)
plt.hist(equ.ravel(),256,[0,256])
plt.show()
Tuy nhiên không phải lúc nào Equalize Histogram toàn bộ ảnh cũng giúp đạt kết quả mong muốn
Image('statue_bright.jpg')
img = cv2.imread('statue_bright.jpg', cv2.IMREAD_GRAYSCALE)
equ = cv2.equalizeHist(img)
plt.imshow(equ, cmap='gray')
Để giải quyết trường hợp này, ta cần dùng một phương pháp Histogram Equalization đặc biệt. Ảnh sẽ được chia thành các khối viên gạch "tiles" nhỏ (tileSize default của OpenCV là 8x8). Sau đó mỗi khối này được Equalize Histogram riêng. Nhờ đó histogram sẽ chỉ giới hạn trong một vùng nhỏ.
Thư viện OpenCV cung cấp hàm:
img = cv2.imread('statue_bright.jpg', cv2.IMREAD_GRAYSCALE)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
img = clahe.apply(img)
cv2.imwrite('newstatue.jpg', img)
Image('newstatue.jpg')
img = cv2.imread('HoGuom.jpg', cv2.IMREAD_GRAYSCALE)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
img[i][j] = int(np.square(int(img[i][j]))/255)
plt.subplot(211)
plt.imshow(img, cmap='gray')
plt.subplot(212)
plt.hist(img.ravel(),256,[0,256])
plt.show()
img = cv2.imread('HoGuom.jpg', cv2.IMREAD_GRAYSCALE)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
img[i][j] = int(np.sqrt(int(img[i][j])))
plt.subplot(211)
plt.imshow(img, cmap='gray')
plt.subplot(212)
plt.hist(img.ravel(),256,[0,256])
plt.show()
\begin{align}{g(i,j) = \alpha \cdot f(i,j) + \beta} \end{align}
Các ham số α>0 và β có thể coi như là tham số điều chỉnh độ tương phản và độ sáng của ảnh.
cv2.convertScaleAbs(image, alpha=alpha, beta=beta) - https://docs.opencv.org/3.4/d2/de8/group__core__array.html#ga3460e9c9f37b563ab9dd550c4d8c4e7d
\begin{align}{O = \left( \frac{I}{255} \right)^{\gamma} \times 255} \end{align}
Với γ<1, các cùng ảnh ban đầu bị tối sẽ được tăng sáng và histogram sẽ có xu hướng dịch chuyển sang phải, ngược lại với γ>1, ảnh sẽ được giảm sáng.
gamma_correction(image, gamma=gamma)
Image('Gamma_Correction.png')
def gamma_correction(img, gamma):
for i in range(img.shape[0]):
for j in range(img.shape[1]):
img[i][j] = ((int(img[i][j])/255.0) ** gamma)*255
return img
img = cv2.imread('HoGuom.jpg', cv2.IMREAD_GRAYSCALE)
img = gamma_correction(img, 2)
cv2.imwrite('gammaHoGuom.jpg', img)
Image('gammaHoGuom.jpg')
img = cv2.imread('HoGuom.jpg', cv2.IMREAD_GRAYSCALE)
img = gamma_correction(img, 0.5)
cv2.imwrite('gammaHoGuom.jpg', img)
Image('gammaHoGuom.jpg')
cv2.filter2D - https://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html#filter2d
Image('himym.jpg')
Averaging kernel - Kernel lấy trung bình các điểm ảnh xung quanh
img = cv2.imread('himym.jpg', cv2.IMREAD_COLOR)
kernel = np.ones((5,5),np.float32)/25
img = cv2.filter2D(img, -1, kernel)
cv2.imwrite('newhimym.jpg', img)
Image('newhimym.jpg')
Sharpening kernel - Kernel tăng độ nét của ảnh
img = cv2.imread('himym.jpg', cv2.IMREAD_COLOR)
kernel_sharpening = np.array([[-1,-1,-1],
[-1, 9,-1],
[-1,-1,-1]])
img = cv2.filter2D(img, -1, kernel_sharpening)
cv2.imwrite('newhimym.jpg', img)
Image('newhimym.jpg')
Một số kernel đặc biệt dùng để làm mịn ảnh.
https://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html#blur
img = cv2.imread('himym.jpg', cv2.IMREAD_COLOR)
# img = cv2.blur(img, (7, 7), 0)
# img = cv2.GaussianBlur(img, (9, 9), 0)
img = cv2.medianBlur(img, 9)
cv2.imwrite('newhimym.jpg', img)
Image('newhimym.jpg')
Khử nhiễu và tăng chất lượng ảnh ở các bài tập sau
Image('deer_salt.jpg')
img = cv2.imread('deer_salt.jpg', cv2.IMREAD_GRAYSCALE)
### YOUR CODE HERE ###
pass
### YOUR CODE HERE ###
cv2.imwrite('newdeer.jpg', img)
Image('newdeer.jpg')
Image('needle1.png')
img = cv2.imread('needle1.png', cv2.IMREAD_GRAYSCALE)
### YOUR CODE HERE ###
pass
### YOUR CODE HERE ###
cv2.imwrite('needle1_new.png', img)
Image('needle1_new.png')
Image('moon_dark.jpg')
img = cv2.imread('moon_dark.jpg', cv2.IMREAD_GRAYSCALE)
### YOUR CODE HERE ###
pass
### YOUR CODE HERE ###
cv2.imwrite('newmoon.jpg', img)
Image('newmoon.jpg')
Image('balloon.jpg')
img = cv2.imread('balloon.jpg', cv2.IMREAD_GRAYSCALE)
### YOUR CODE HERE ###
pass
### YOUR CODE HERE ###
cv2.imwrite('newballoon.jpg', img)
Image('newballoon.jpg')
Image('girl1_dark.jpg')
img = cv2.imread('girl1_dark.jpg')
img = cv2.imread('girl1_dark.jpg')
### YOUR CODE HERE ###
pass
### YOUR CODE HERE ###
cv2.imwrite('newgirl1.jpg', img)
Image('newgirl1.jpg')
Sử dụng các phương pháp cải thiện chất lượng ảnh đã học để cải thiện các ảnh trong thư mục homework. Đối với các trường hợp sử dụng cân bằng histogram, vẽ histogram của ảnh trước và sau khi áp dụng.
Image('homework/noise.png')
Image('homework/needle2.png')
Image('homework/kid.png')
Image('homework/hand.jpg')
Image('homework/girl2_dark.jpg')
Image('homework/mountain_dark.jpg')